package org.fitweb.files;

import org.junit.Test;

import java.io.File;

import static java.io.File.*;
import static org.fitweb.files.FileMaker.*;
import static org.junit.Assert.*;

public class PathFinderTest {

    private FileMaker make = new FileMaker();

    public static String safePath(String filePath) {
        return separator.equals("\\") ? filePath.replaceAll("/", "\\\\") : filePath;
    }

    @Test
    public void canGetRelativeFilesForItemsWithinAKnownDirectoryTree() throws Exception {
        File ancestor = make.directory(tempDir(), "ancestor");
        File subFolder = make.directory(ancestor, "subFolder");
        File descendant = make.file(subFolder, "myOwn.file");

        File relativeFile = PathFinder.relativeFile(ancestor, descendant);

        assertTrue(relativeFile.getPath().startsWith("subFolder"));
        assertTrue(relativeFile.getPath().endsWith("file"));
    }

    @Test
    public void cannotHaveARelativeAncestorAndAbsoluteDescendant() throws Exception {
        try {
            assertEquals(safePath("given/path/toFile.txt"), given(
                    relative("ancestor/"),
                    absolute("ancestor/given/path/toFile.txt")));
        } catch (IllegalStateException e) {
            assertEquals("Please provide an absolute file for the ancestor, if the descendant is absolute", e.getMessage());
        }
    }

    @Test
    public void acceptsRelativeAndAbsoluteFilesForAncestorAndDescendant() throws Exception {
        assertEquals(safePath("given/path/toFile.txt"), given(
                relative("ancestor/"),
                relative("given/path/toFile.txt")));

        assertEquals("fileInRoot.txt", given(
                relative("ancestor/"),
                relative("fileInRoot.txt")));

        assertEquals(safePath("given/path/toFile.txt"), given(
                absolute("ancestor/"),
                absolute("ancestor/given/path/toFile.txt")));

        assertEquals(safePath("given/path/toFile.txt"), given(
                relative("ancestor/"),
                absolute("ancestor/given/path/toFile.txt")));

        assertEquals(safePath("given/path/toFile.txt"), given(
                absolute("ancestor/"),
                relative("given/path/toFile.txt")));
    }

    @Test
    public void removesAncestorFromDescendantPath() throws Exception {
        assertEquals(safePath("given/path/toFile.txt"), given(
                relative("ancestor/"),
                relative("ancestor/given/path/toFile.txt")));
    }

    private File relative(String path) {
        File file = new File(path);
        assertFalse(file.isAbsolute());
        return file;
    }

    private File absolute(String path) {
        File file = new File(System.getProperty("user.dir"), path);
        assertTrue(file.isAbsolute());
        return file;
    }

    private String given(File ancestor, File descendant) {
        return PathFinder.relativeFile(ancestor, descendant).getPath();
    }
}
